/***********************************************************************************************************************
*  OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
*  See also https://openstudio.net/license
***********************************************************************************************************************/

#include "EvaporativeFluidCoolerSingleSpeed.hpp"
#include "EvaporativeFluidCoolerSingleSpeed_Impl.hpp"
#include "Schedule.hpp"
#include "Schedule_Impl.hpp"
#include "ScheduleTypeLimits.hpp"
#include "ScheduleTypeRegistry.hpp"
#include "PlantLoop.hpp"
#include "PlantLoop_Impl.hpp"
#include "ConnectorSplitter.hpp"
#include "ConnectorSplitter_Impl.hpp"
#include "ConnectorMixer.hpp"
#include "ConnectorMixer_Impl.hpp"
#include "ModelObject.hpp"
#include "ModelObject_Impl.hpp"
#include "Model.hpp"
#include "Model_Impl.hpp"
#include "Node.hpp"
#include "Node_Impl.hpp"
#include "PortList.hpp"
#include "PortList_Impl.hpp"

#include "../utilities/core/Assert.hpp"
#include "../utilities/data/DataEnums.hpp"

#include <utilities/idd/IddFactory.hxx>
#include <utilities/idd/OS_EvaporativeFluidCooler_SingleSpeed_FieldEnums.hxx>
#include <utilities/idd/IddEnums.hxx>

namespace openstudio {
namespace model {

  namespace detail {

    EvaporativeFluidCoolerSingleSpeed_Impl::EvaporativeFluidCoolerSingleSpeed_Impl(const IdfObject& idfObject, Model_Impl* model, bool keepHandle)
      : StraightComponent_Impl(idfObject, model, keepHandle) {
      OS_ASSERT(idfObject.iddObject().type() == EvaporativeFluidCoolerSingleSpeed::iddObjectType());
    }

    EvaporativeFluidCoolerSingleSpeed_Impl::EvaporativeFluidCoolerSingleSpeed_Impl(const openstudio::detail::WorkspaceObject_Impl& other,
                                                                                   Model_Impl* model, bool keepHandle)
      : StraightComponent_Impl(other, model, keepHandle) {
      OS_ASSERT(other.iddObject().type() == EvaporativeFluidCoolerSingleSpeed::iddObjectType());
    }

    EvaporativeFluidCoolerSingleSpeed_Impl::EvaporativeFluidCoolerSingleSpeed_Impl(const EvaporativeFluidCoolerSingleSpeed_Impl& other,
                                                                                   Model_Impl* model, bool keepHandle)
      : StraightComponent_Impl(other, model, keepHandle) {}

    const std::vector<std::string>& EvaporativeFluidCoolerSingleSpeed_Impl::outputVariableNames() const {
      static const std::vector<std::string> result{
        "Cooling Tower Fan Electricity Rate",
        "Cooling Tower Fan Electricity Energy",
        "Cooling Tower Heat Transfer Rate",
        "Cooling Tower Inlet Temperature",
        "Cooling Tower Outlet Temperature",
        "Cooling Tower Mass Flow Rate",
        "Cooling Tower Bypass Fraction",
        "Cooling Tower Make Up Water Volume Flow Rate",
        "Cooling Tower Make Up Water Volume",
        "Cooling Tower Water Evaporation Volume Flow Rate",
        "Cooling Tower Water Evaporation Volume",
        "Cooling Tower Water Drift Volume Flow Rate",
        "Evaporative Fluid Cooler Water Drift",
        "Cooling Tower Water Blowdown Volume Flow Rate",
        "Cooling Tower Water Blowdown Volume",
        "Cooling Tower Make Up Mains Water Volume"
        // If Supply Water Storage Tank Name is specified:
        // TODO: not implemented for now
        //"Cooling Tower Storage Tank Water Volume Flow Rate",
        //"Cooling Tower Storage Tank Water Volume",
        //"Cooling Tower Starved Storage Tank Water Volume Flow Rate",
        //"Cooling Tower Starved Storage Tank Water Volume"
      };
      return result;
    }

    IddObjectType EvaporativeFluidCoolerSingleSpeed_Impl::iddObjectType() const {
      return EvaporativeFluidCoolerSingleSpeed::iddObjectType();
    }

    std::vector<ScheduleTypeKey> EvaporativeFluidCoolerSingleSpeed_Impl::getScheduleTypeKeys(const Schedule& schedule) const {
      std::vector<ScheduleTypeKey> result;
      UnsignedVector fieldIndices = getSourceIndices(schedule.handle());
      UnsignedVector::const_iterator b(fieldIndices.begin());
      UnsignedVector::const_iterator e(fieldIndices.end());
      if (std::find(b, e, OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownMakeupWaterUsageScheduleName) != e) {
        result.push_back(ScheduleTypeKey("EvaporativeFluidCoolerSingleSpeed", "Blowdown Makeup Water Usage"));
      }
      return result;
    }

    unsigned EvaporativeFluidCoolerSingleSpeed_Impl::inletPort() const {
      return OS_EvaporativeFluidCooler_SingleSpeedFields::WaterInletNodeName;
    }

    unsigned EvaporativeFluidCoolerSingleSpeed_Impl::outletPort() const {
      return OS_EvaporativeFluidCooler_SingleSpeedFields::WaterOutletNodeName;
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::addToNode(Node& node) {
      if (boost::optional<PlantLoop> plant = node.plantLoop()) {
        if (plant->supplyComponent(node.handle())) {
          return StraightComponent_Impl::addToNode(node);
        }
      }

      return false;
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::designAirFlowRate() const {
      return getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRate, true);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isDesignAirFlowRateAutosized() const {
      bool result = false;
      boost::optional<std::string> value = getString(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRate, true);
      if (value) {
        result = openstudio::istringEqual(value.get(), "autosize");
      }
      return result;
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::fanPoweratDesignAirFlowRate() const {
      return getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::FanPoweratDesignAirFlowRate, true);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isFanPoweratDesignAirFlowRateAutosized() const {
      bool result = false;
      boost::optional<std::string> value = getString(OS_EvaporativeFluidCooler_SingleSpeedFields::FanPoweratDesignAirFlowRate, true);
      if (value) {
        result = openstudio::istringEqual(value.get(), "autosize");
      }
      return result;
    }

    double EvaporativeFluidCoolerSingleSpeed_Impl::designSprayWaterFlowRate() const {
      boost::optional<double> value = getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignSprayWaterFlowRate, true);
      OS_ASSERT(value);
      return value.get();
    }

    std::string EvaporativeFluidCoolerSingleSpeed_Impl::performanceInputMethod() const {
      boost::optional<std::string> value = getString(OS_EvaporativeFluidCooler_SingleSpeedFields::PerformanceInputMethod, true);
      OS_ASSERT(value);
      return value.get();
    }

    double EvaporativeFluidCoolerSingleSpeed_Impl::heatRejectionCapacityandNominalCapacitySizingRatio() const {
      boost::optional<double> value =
        getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::HeatRejectionCapacityandNominalCapacitySizingRatio, true);
      OS_ASSERT(value);
      return value.get();
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::standardDesignCapacity() const {
      return getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::StandardDesignCapacity, true);
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::ufactorTimesAreaValueatDesignAirFlowRate() const {
      return getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::UfactorTimesAreaValueatDesignAirFlowRate, true);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isUfactorTimesAreaValueatDesignAirFlowRateAutosized() const {
      bool result = false;
      boost::optional<std::string> value = getString(OS_EvaporativeFluidCooler_SingleSpeedFields::UfactorTimesAreaValueatDesignAirFlowRate, true);
      if (value) {
        result = openstudio::istringEqual(value.get(), "autosize");
      }
      return result;
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::designWaterFlowRate() const {
      return getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignWaterFlowRate, true);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isDesignWaterFlowRateAutosized() const {
      bool result = false;
      boost::optional<std::string> value = getString(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignWaterFlowRate, true);
      if (value) {
        result = openstudio::istringEqual(value.get(), "autosize");
      }
      return result;
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::userSpecifiedDesignCapacity() const {
      return getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::UserSpecifiedDesignCapacity, true);
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::designEnteringWaterTemperature() const {
      return getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringWaterTemperature, true);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isDesignEnteringWaterTemperatureAutosized() const {
      bool result = false;
      boost::optional<std::string> value = getString(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringWaterTemperature, true);
      if (value) {
        result = openstudio::istringEqual(value.get(), "autosize");
      }
      return result;
    }

    double EvaporativeFluidCoolerSingleSpeed_Impl::designEnteringAirTemperature() const {
      boost::optional<double> value = getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringAirTemperature, true);
      OS_ASSERT(value);
      return value.get();
    }

    double EvaporativeFluidCoolerSingleSpeed_Impl::designEnteringAirWetbulbTemperature() const {
      boost::optional<double> value = getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringAirWetbulbTemperature, true);
      OS_ASSERT(value);
      return value.get();
    }

    std::string EvaporativeFluidCoolerSingleSpeed_Impl::capacityControl() const {
      boost::optional<std::string> value = getString(OS_EvaporativeFluidCooler_SingleSpeedFields::CapacityControl, true);
      OS_ASSERT(value);
      return value.get();
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isCapacityControlDefaulted() const {
      return isEmpty(OS_EvaporativeFluidCooler_SingleSpeedFields::CapacityControl);
    }

    double EvaporativeFluidCoolerSingleSpeed_Impl::sizingFactor() const {
      boost::optional<double> value = getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::SizingFactor, true);
      OS_ASSERT(value);
      return value.get();
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isSizingFactorDefaulted() const {
      return isEmpty(OS_EvaporativeFluidCooler_SingleSpeedFields::SizingFactor);
    }

    std::string EvaporativeFluidCoolerSingleSpeed_Impl::evaporationLossMode() const {
      boost::optional<std::string> value = getString(OS_EvaporativeFluidCooler_SingleSpeedFields::EvaporationLossMode, true);
      OS_ASSERT(value);
      return value.get();
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isEvaporationLossModeDefaulted() const {
      return isEmpty(OS_EvaporativeFluidCooler_SingleSpeedFields::EvaporationLossMode);
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::evaporationLossFactor() const {
      return getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::EvaporationLossFactor, true);
    }

    double EvaporativeFluidCoolerSingleSpeed_Impl::driftLossPercent() const {
      boost::optional<double> value = getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DriftLossPercent, true);
      OS_ASSERT(value);
      return value.get();
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isDriftLossPercentDefaulted() const {
      return isEmpty(OS_EvaporativeFluidCooler_SingleSpeedFields::DriftLossPercent);
    }

    std::string EvaporativeFluidCoolerSingleSpeed_Impl::blowdownCalculationMode() const {
      boost::optional<std::string> value = getString(OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownCalculationMode, true);
      OS_ASSERT(value);
      return value.get();
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isBlowdownCalculationModeDefaulted() const {
      return isEmpty(OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownCalculationMode);
    }

    double EvaporativeFluidCoolerSingleSpeed_Impl::blowdownConcentrationRatio() const {
      boost::optional<double> value = getDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownConcentrationRatio, true);
      OS_ASSERT(value);
      return value.get();
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::isBlowdownConcentrationRatioDefaulted() const {
      return isEmpty(OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownConcentrationRatio);
    }

    boost::optional<Schedule> EvaporativeFluidCoolerSingleSpeed_Impl::blowdownMakeupWaterUsageSchedule() const {
      return getObject<ModelObject>().getModelObjectTarget<Schedule>(
        OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownMakeupWaterUsageScheduleName);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setDesignAirFlowRate(boost::optional<double> designAirFlowRate) {
      bool result(false);
      if (designAirFlowRate) {
        result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRate, designAirFlowRate.get());
      }
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::autosizeDesignAirFlowRate() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignAirFlowRate, "autosize");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setFanPoweratDesignAirFlowRate(boost::optional<double> fanPoweratDesignAirFlowRate) {
      bool result(false);
      if (fanPoweratDesignAirFlowRate) {
        result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::FanPoweratDesignAirFlowRate, fanPoweratDesignAirFlowRate.get());
      }
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::autosizeFanPoweratDesignAirFlowRate() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::FanPoweratDesignAirFlowRate, "autosize");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setDesignSprayWaterFlowRate(double designSprayWaterFlowRate) {
      bool result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignSprayWaterFlowRate, designSprayWaterFlowRate);
      return result;
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setPerformanceInputMethod(const std::string& performanceInputMethod) {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::PerformanceInputMethod, performanceInputMethod);
      return result;
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setHeatRejectionCapacityandNominalCapacitySizingRatio(
      double heatRejectionCapacityandNominalCapacitySizingRatio) {
      bool result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::HeatRejectionCapacityandNominalCapacitySizingRatio,
                              heatRejectionCapacityandNominalCapacitySizingRatio);
      OS_ASSERT(result);
      return result;
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setStandardDesignCapacity(boost::optional<double> standardDesignCapacity) {
      bool result(false);
      if (standardDesignCapacity) {
        result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::StandardDesignCapacity, standardDesignCapacity.get());
      } else {
        resetStandardDesignCapacity();
        result = true;
      }
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetStandardDesignCapacity() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::StandardDesignCapacity, "");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setUfactorTimesAreaValueatDesignAirFlowRate(
      boost::optional<double> ufactorTimesAreaValueatDesignAirFlowRate) {
      bool result(false);
      if (ufactorTimesAreaValueatDesignAirFlowRate) {
        result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::UfactorTimesAreaValueatDesignAirFlowRate,
                           ufactorTimesAreaValueatDesignAirFlowRate.get());
      } else {
        resetUfactorTimesAreaValueatDesignAirFlowRate();
        result = true;
      }
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetUfactorTimesAreaValueatDesignAirFlowRate() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::UfactorTimesAreaValueatDesignAirFlowRate, "");
      OS_ASSERT(result);
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::autosizeUfactorTimesAreaValueatDesignAirFlowRate() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::UfactorTimesAreaValueatDesignAirFlowRate, "autosize");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setDesignWaterFlowRate(boost::optional<double> designWaterFlowRate) {
      bool result(false);
      if (designWaterFlowRate) {
        result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignWaterFlowRate, designWaterFlowRate.get());
      } else {
        resetDesignWaterFlowRate();
        result = true;
      }
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetDesignWaterFlowRate() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignWaterFlowRate, "");
      OS_ASSERT(result);
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::autosizeDesignWaterFlowRate() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignWaterFlowRate, "autosize");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setUserSpecifiedDesignCapacity(boost::optional<double> userSpecifiedDesignCapacity) {
      bool result(false);
      if (userSpecifiedDesignCapacity) {
        result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::UserSpecifiedDesignCapacity, userSpecifiedDesignCapacity.get());
      } else {
        resetUserSpecifiedDesignCapacity();
        result = true;
      }
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetUserSpecifiedDesignCapacity() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::UserSpecifiedDesignCapacity, "");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setDesignEnteringWaterTemperature(boost::optional<double> designEnteringWaterTemperature) {
      bool result(false);
      if (designEnteringWaterTemperature) {
        result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringWaterTemperature, designEnteringWaterTemperature.get());
      }
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::autosizeDesignEnteringWaterTemperature() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringWaterTemperature, "autosize");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setDesignEnteringAirTemperature(boost::optional<double> designEnteringAirTemperature) {
      bool result(false);
      if (designEnteringAirTemperature) {
        result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringAirTemperature, designEnteringAirTemperature.get());
      }
      return result;
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setDesignEnteringAirWetbulbTemperature(boost::optional<double> designEnteringAirWetbulbTemperature) {
      bool result(false);
      if (designEnteringAirWetbulbTemperature) {
        result =
          setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DesignEnteringAirWetbulbTemperature, designEnteringAirWetbulbTemperature.get());
      }
      return result;
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setCapacityControl(const std::string& capacityControl) {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::CapacityControl, capacityControl);
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetCapacityControl() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::CapacityControl, "");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setSizingFactor(double sizingFactor) {
      bool result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::SizingFactor, sizingFactor);
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetSizingFactor() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::SizingFactor, "");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setEvaporationLossMode(const std::string& evaporationLossMode) {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::EvaporationLossMode, evaporationLossMode);
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetEvaporationLossMode() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::EvaporationLossMode, "");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setEvaporationLossFactor(boost::optional<double> evaporationLossFactor) {
      bool result(false);
      if (evaporationLossFactor) {
        result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::EvaporationLossFactor, evaporationLossFactor.get());
      } else {
        resetEvaporationLossFactor();
        result = true;
      }
      OS_ASSERT(result);
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetEvaporationLossFactor() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::EvaporationLossFactor, "");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setDriftLossPercent(double driftLossPercent) {
      bool result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::DriftLossPercent, driftLossPercent);
      OS_ASSERT(result);
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetDriftLossPercent() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::DriftLossPercent, "");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setBlowdownCalculationMode(const std::string& blowdownCalculationMode) {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownCalculationMode, blowdownCalculationMode);
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetBlowdownCalculationMode() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownCalculationMode, "");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setBlowdownConcentrationRatio(double blowdownConcentrationRatio) {
      bool result = setDouble(OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownConcentrationRatio, blowdownConcentrationRatio);
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetBlowdownConcentrationRatio() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownConcentrationRatio, "");
      OS_ASSERT(result);
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setBlowdownMakeupWaterUsageSchedule(Schedule& schedule) {
      bool result = setSchedule(OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownMakeupWaterUsageScheduleName,
                                "EvaporativeFluidCoolerSingleSpeed", "Blowdown Makeup Water Usage", schedule);
      return result;
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::resetBlowdownMakeupWaterUsageSchedule() {
      bool result = setString(OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownMakeupWaterUsageScheduleName, "");
      OS_ASSERT(result);
    }

    std::vector<std::string> EvaporativeFluidCoolerSingleSpeed_Impl::performanceInputMethodValues() const {
      return EvaporativeFluidCoolerSingleSpeed::performanceInputMethodValues();
    }

    std::vector<std::string> EvaporativeFluidCoolerSingleSpeed_Impl::capacityControlValues() const {
      return EvaporativeFluidCoolerSingleSpeed::capacityControlValues();
    }

    std::vector<std::string> EvaporativeFluidCoolerSingleSpeed_Impl::evaporationLossModeValues() const {
      return EvaporativeFluidCoolerSingleSpeed::evaporationLossModeValues();
    }

    std::vector<std::string> EvaporativeFluidCoolerSingleSpeed_Impl::blowdownCalculationModeValues() const {
      return EvaporativeFluidCoolerSingleSpeed::blowdownCalculationModeValues();
    }

    boost::optional<ModelObject> EvaporativeFluidCoolerSingleSpeed_Impl::blowdownMakeupWaterUsageScheduleAsModelObject() const {
      OptionalModelObject result;
      OptionalSchedule intermediate = blowdownMakeupWaterUsageSchedule();
      if (intermediate) {
        result = *intermediate;
      }
      return result;
    }

    bool EvaporativeFluidCoolerSingleSpeed_Impl::setBlowdownMakeupWaterUsageScheduleAsModelObject(const boost::optional<ModelObject>& modelObject) {
      if (modelObject) {
        OptionalSchedule intermediate = modelObject->optionalCast<Schedule>();
        if (intermediate) {
          Schedule schedule(*intermediate);
          return setBlowdownMakeupWaterUsageSchedule(schedule);
        } else {
          return false;
        }
      } else {
        resetBlowdownMakeupWaterUsageSchedule();
      }
      return true;
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::autosizedDesignAirFlowRate() const {
      return getAutosizedValue("Design Air Flow Rate", "m3/s");
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::autosizedFanPoweratDesignAirFlowRate() const {
      return getAutosizedValue("Fan Power at Design Air Flow Rate", "W");
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::autosizedUfactorTimesAreaValueatDesignAirFlowRate() const {
      return getAutosizedValue("U-Factor Times Area Value at Design Air Flow Rate", "W/C");
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::autosizedDesignWaterFlowRate() const {
      return getAutosizedValue("Design Water Flow Rate", "m3/s");
    }

    boost::optional<double> EvaporativeFluidCoolerSingleSpeed_Impl::autosizedDesignEnteringWaterTemperature() const {
      return getAutosizedValue("Design Entering Water Temperature", "C");
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::autosize() {
      autosizeDesignAirFlowRate();
      autosizeFanPoweratDesignAirFlowRate();
      autosizeUfactorTimesAreaValueatDesignAirFlowRate();
      autosizeDesignWaterFlowRate();
      autosizeDesignEnteringWaterTemperature();
    }

    void EvaporativeFluidCoolerSingleSpeed_Impl::applySizingValues() {
      boost::optional<double> val;
      val = autosizedDesignAirFlowRate();
      if (val) {
        setDesignAirFlowRate(val.get());
      }

      val = autosizedFanPoweratDesignAirFlowRate();
      if (val) {
        setFanPoweratDesignAirFlowRate(val.get());
      }

      val = autosizedUfactorTimesAreaValueatDesignAirFlowRate();
      if (val) {
        setUfactorTimesAreaValueatDesignAirFlowRate(val.get());
      }

      val = autosizedDesignWaterFlowRate();
      if (val) {
        setDesignWaterFlowRate(val.get());
      }

      val = autosizedDesignEnteringWaterTemperature();
      if (val) {
        setDesignEnteringWaterTemperature(val.get());
      }
    }

    ComponentType EvaporativeFluidCoolerSingleSpeed_Impl::componentType() const {
      return ComponentType::Cooling;
    }

    std::vector<FuelType> EvaporativeFluidCoolerSingleSpeed_Impl::coolingFuelTypes() const {
      return {FuelType::Electricity};
    }

    std::vector<FuelType> EvaporativeFluidCoolerSingleSpeed_Impl::heatingFuelTypes() const {
      return {};
    }

    std::vector<AppGFuelType> EvaporativeFluidCoolerSingleSpeed_Impl::appGHeatingFuelTypes() const {
      return {};
    }

  }  // namespace detail

  EvaporativeFluidCoolerSingleSpeed::EvaporativeFluidCoolerSingleSpeed(const Model& model)
    : StraightComponent(EvaporativeFluidCoolerSingleSpeed::iddObjectType(), model) {
    OS_ASSERT(getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>());

    bool ok = true;
    autosizeDesignAirFlowRate();
    autosizeFanPoweratDesignAirFlowRate();
    ok = setDesignSprayWaterFlowRate(0.03);
    OS_ASSERT(ok);
    ok = setPerformanceInputMethod("UFactorTimesAreaAndDesignWaterFlowRate");
    OS_ASSERT(ok);
    ok = setHeatRejectionCapacityandNominalCapacitySizingRatio(1.25);
    OS_ASSERT(ok);
    resetStandardDesignCapacity();
    autosizeUfactorTimesAreaValueatDesignAirFlowRate();
    autosizeDesignWaterFlowRate();
    resetUserSpecifiedDesignCapacity();
    autosizeDesignEnteringWaterTemperature();
    ok = setDesignEnteringAirTemperature(35.0);
    OS_ASSERT(ok);
    ok = setDesignEnteringAirWetbulbTemperature(25.6);
    OS_ASSERT(ok);
    ok = setCapacityControl("FanCycling");
    OS_ASSERT(ok);
    ok = setSizingFactor(1.0);
    OS_ASSERT(ok);
    ok = setEvaporationLossMode("SaturatedExit");
    OS_ASSERT(ok);
    ok = setDriftLossPercent(0.008);
    OS_ASSERT(ok);
    ok = setBlowdownCalculationMode("ConcentrationRatio");
    OS_ASSERT(ok);
    ok = setBlowdownConcentrationRatio(3.0);
    OS_ASSERT(ok);
    resetBlowdownMakeupWaterUsageSchedule();
    setString(OS_EvaporativeFluidCooler_SingleSpeedFields::SupplyWaterStorageTankName, "");
  }

  IddObjectType EvaporativeFluidCoolerSingleSpeed::iddObjectType() {
    return {IddObjectType::OS_EvaporativeFluidCooler_SingleSpeed};
  }

  std::vector<std::string> EvaporativeFluidCoolerSingleSpeed::performanceInputMethodValues() {
    return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(),
                          OS_EvaporativeFluidCooler_SingleSpeedFields::PerformanceInputMethod);
  }

  std::vector<std::string> EvaporativeFluidCoolerSingleSpeed::capacityControlValues() {
    return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), OS_EvaporativeFluidCooler_SingleSpeedFields::CapacityControl);
  }

  std::vector<std::string> EvaporativeFluidCoolerSingleSpeed::evaporationLossModeValues() {
    return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(), OS_EvaporativeFluidCooler_SingleSpeedFields::EvaporationLossMode);
  }

  std::vector<std::string> EvaporativeFluidCoolerSingleSpeed::blowdownCalculationModeValues() {
    return getIddKeyNames(IddFactory::instance().getObject(iddObjectType()).get(),
                          OS_EvaporativeFluidCooler_SingleSpeedFields::BlowdownCalculationMode);
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::designAirFlowRate() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->designAirFlowRate();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isDesignAirFlowRateAutosized() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isDesignAirFlowRateAutosized();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::fanPoweratDesignAirFlowRate() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->fanPoweratDesignAirFlowRate();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isFanPoweratDesignAirFlowRateAutosized() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isFanPoweratDesignAirFlowRateAutosized();
  }

  double EvaporativeFluidCoolerSingleSpeed::designSprayWaterFlowRate() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->designSprayWaterFlowRate();
  }

  std::string EvaporativeFluidCoolerSingleSpeed::performanceInputMethod() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->performanceInputMethod();
  }

  double EvaporativeFluidCoolerSingleSpeed::heatRejectionCapacityandNominalCapacitySizingRatio() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->heatRejectionCapacityandNominalCapacitySizingRatio();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::standardDesignCapacity() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->standardDesignCapacity();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::ufactorTimesAreaValueatDesignAirFlowRate() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->ufactorTimesAreaValueatDesignAirFlowRate();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isUfactorTimesAreaValueatDesignAirFlowRateAutosized() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isUfactorTimesAreaValueatDesignAirFlowRateAutosized();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::designWaterFlowRate() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->designWaterFlowRate();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isDesignWaterFlowRateAutosized() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isDesignWaterFlowRateAutosized();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::userSpecifiedDesignCapacity() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->userSpecifiedDesignCapacity();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::designEnteringWaterTemperature() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->designEnteringWaterTemperature();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isDesignEnteringWaterTemperatureAutosized() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isDesignEnteringWaterTemperatureAutosized();
  }

  double EvaporativeFluidCoolerSingleSpeed::designEnteringAirTemperature() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->designEnteringAirTemperature();
  }

  double EvaporativeFluidCoolerSingleSpeed::designEnteringAirWetbulbTemperature() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->designEnteringAirWetbulbTemperature();
  }

  std::string EvaporativeFluidCoolerSingleSpeed::capacityControl() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->capacityControl();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isCapacityControlDefaulted() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isCapacityControlDefaulted();
  }

  double EvaporativeFluidCoolerSingleSpeed::sizingFactor() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->sizingFactor();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isSizingFactorDefaulted() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isSizingFactorDefaulted();
  }

  std::string EvaporativeFluidCoolerSingleSpeed::evaporationLossMode() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->evaporationLossMode();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isEvaporationLossModeDefaulted() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isEvaporationLossModeDefaulted();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::evaporationLossFactor() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->evaporationLossFactor();
  }

  double EvaporativeFluidCoolerSingleSpeed::driftLossPercent() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->driftLossPercent();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isDriftLossPercentDefaulted() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isDriftLossPercentDefaulted();
  }

  std::string EvaporativeFluidCoolerSingleSpeed::blowdownCalculationMode() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->blowdownCalculationMode();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isBlowdownCalculationModeDefaulted() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isBlowdownCalculationModeDefaulted();
  }

  double EvaporativeFluidCoolerSingleSpeed::blowdownConcentrationRatio() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->blowdownConcentrationRatio();
  }

  bool EvaporativeFluidCoolerSingleSpeed::isBlowdownConcentrationRatioDefaulted() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->isBlowdownConcentrationRatioDefaulted();
  }

  boost::optional<Schedule> EvaporativeFluidCoolerSingleSpeed::blowdownMakeupWaterUsageSchedule() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->blowdownMakeupWaterUsageSchedule();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setDesignAirFlowRate(double designAirFlowRate) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setDesignAirFlowRate(designAirFlowRate);
  }

  void EvaporativeFluidCoolerSingleSpeed::autosizeDesignAirFlowRate() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->autosizeDesignAirFlowRate();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setFanPoweratDesignAirFlowRate(double fanPoweratDesignAirFlowRate) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setFanPoweratDesignAirFlowRate(fanPoweratDesignAirFlowRate);
  }

  void EvaporativeFluidCoolerSingleSpeed::autosizeFanPoweratDesignAirFlowRate() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->autosizeFanPoweratDesignAirFlowRate();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setDesignSprayWaterFlowRate(double designSprayWaterFlowRate) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setDesignSprayWaterFlowRate(designSprayWaterFlowRate);
  }

  bool EvaporativeFluidCoolerSingleSpeed::setPerformanceInputMethod(const std::string& performanceInputMethod) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setPerformanceInputMethod(performanceInputMethod);
  }

  bool EvaporativeFluidCoolerSingleSpeed::setHeatRejectionCapacityandNominalCapacitySizingRatio(
    double heatRejectionCapacityandNominalCapacitySizingRatio) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setHeatRejectionCapacityandNominalCapacitySizingRatio(
      heatRejectionCapacityandNominalCapacitySizingRatio);
  }

  bool EvaporativeFluidCoolerSingleSpeed::setStandardDesignCapacity(double standardDesignCapacity) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setStandardDesignCapacity(standardDesignCapacity);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetStandardDesignCapacity() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetStandardDesignCapacity();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setUfactorTimesAreaValueatDesignAirFlowRate(double ufactorTimesAreaValueatDesignAirFlowRate) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setUfactorTimesAreaValueatDesignAirFlowRate(
      ufactorTimesAreaValueatDesignAirFlowRate);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetUfactorTimesAreaValueatDesignAirFlowRate() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetUfactorTimesAreaValueatDesignAirFlowRate();
  }

  void EvaporativeFluidCoolerSingleSpeed::autosizeUfactorTimesAreaValueatDesignAirFlowRate() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->autosizeUfactorTimesAreaValueatDesignAirFlowRate();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setDesignWaterFlowRate(double designWaterFlowRate) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setDesignWaterFlowRate(designWaterFlowRate);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetDesignWaterFlowRate() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetDesignWaterFlowRate();
  }

  void EvaporativeFluidCoolerSingleSpeed::autosizeDesignWaterFlowRate() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->autosizeDesignWaterFlowRate();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setUserSpecifiedDesignCapacity(double userSpecifiedDesignCapacity) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setUserSpecifiedDesignCapacity(userSpecifiedDesignCapacity);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetUserSpecifiedDesignCapacity() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetUserSpecifiedDesignCapacity();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setDesignEnteringWaterTemperature(double designEnteringWaterTemperature) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setDesignEnteringWaterTemperature(designEnteringWaterTemperature);
  }

  void EvaporativeFluidCoolerSingleSpeed::autosizeDesignEnteringWaterTemperature() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->autosizeDesignEnteringWaterTemperature();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setDesignEnteringAirTemperature(double designEnteringAirTemperature) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setDesignEnteringAirTemperature(designEnteringAirTemperature);
  }

  bool EvaporativeFluidCoolerSingleSpeed::setDesignEnteringAirWetbulbTemperature(double designEnteringAirWetbulbTemperature) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setDesignEnteringAirWetbulbTemperature(designEnteringAirWetbulbTemperature);
  }

  bool EvaporativeFluidCoolerSingleSpeed::setCapacityControl(const std::string& capacityControl) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setCapacityControl(capacityControl);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetCapacityControl() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetCapacityControl();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setSizingFactor(double sizingFactor) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setSizingFactor(sizingFactor);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetSizingFactor() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetSizingFactor();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setEvaporationLossMode(const std::string& evaporationLossMode) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setEvaporationLossMode(evaporationLossMode);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetEvaporationLossMode() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetEvaporationLossMode();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setEvaporationLossFactor(double evaporationLossFactor) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setEvaporationLossFactor(evaporationLossFactor);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetEvaporationLossFactor() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetEvaporationLossFactor();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setDriftLossPercent(double driftLossPercent) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setDriftLossPercent(driftLossPercent);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetDriftLossPercent() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetDriftLossPercent();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setBlowdownCalculationMode(const std::string& blowdownCalculationMode) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setBlowdownCalculationMode(blowdownCalculationMode);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetBlowdownCalculationMode() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetBlowdownCalculationMode();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setBlowdownConcentrationRatio(double blowdownConcentrationRatio) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setBlowdownConcentrationRatio(blowdownConcentrationRatio);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetBlowdownConcentrationRatio() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetBlowdownConcentrationRatio();
  }

  bool EvaporativeFluidCoolerSingleSpeed::setBlowdownMakeupWaterUsageSchedule(Schedule& schedule) {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->setBlowdownMakeupWaterUsageSchedule(schedule);
  }

  void EvaporativeFluidCoolerSingleSpeed::resetBlowdownMakeupWaterUsageSchedule() {
    getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->resetBlowdownMakeupWaterUsageSchedule();
  }

  /// @cond
  EvaporativeFluidCoolerSingleSpeed::EvaporativeFluidCoolerSingleSpeed(std::shared_ptr<detail::EvaporativeFluidCoolerSingleSpeed_Impl> impl)
    : StraightComponent(std::move(impl)) {}
  /// @endcond

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::autosizedDesignAirFlowRate() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->autosizedDesignAirFlowRate();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::autosizedFanPoweratDesignAirFlowRate() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->autosizedFanPoweratDesignAirFlowRate();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::autosizedUfactorTimesAreaValueatDesignAirFlowRate() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->autosizedUfactorTimesAreaValueatDesignAirFlowRate();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::autosizedDesignWaterFlowRate() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->autosizedDesignWaterFlowRate();
  }

  boost::optional<double> EvaporativeFluidCoolerSingleSpeed::autosizedDesignEnteringWaterTemperature() const {
    return getImpl<detail::EvaporativeFluidCoolerSingleSpeed_Impl>()->autosizedDesignEnteringWaterTemperature();
  }

}  // namespace model
}  // namespace openstudio
